#ifndef _FNT_ANNOT_TREE_H_
#define _FNT_ANNOT_TREE_H_

#include <QColor>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <condition_variable>
#include <QAbstractItemModel>

#include "annot.h"

class AnnotTree {
	enum class State {
		Empty=0,
		Loading,
		Ready,
		Error
	};

	int _id;
	QString _loc;
	uint32_t _root_num;
	std::vector<AnnotItem> _items;
	std::unordered_map<uint64_t, uint32_t> _maps;

	State _state;
	std::mutex _mtx;
	std::condition_variable _cv;

	AnnotTree(const AnnotTree&) =delete;
	AnnotTree& operator=(const AnnotTree&) =delete;

	void load(std::istream& fs);
	bool waitLoading();

	public:
	AnnotTree(int id, const QString& loc):
		_id{id}, _loc{loc},
		_root_num{0}, _items{0},
		_state{State::Empty}, _mtx{}, _cv{}
	{
	}
	~AnnotTree() {
	}


	const std::vector<AnnotItem>& annots() const {
		return _items;
	}
	const AnnotItem* annot(uint32_t id) const {
		if(id>0 && id<=_items.size())
			return &_items[id-1];
		return nullptr;
	}

	uint32_t size() const {
		return _items.size();
	}

	uint32_t root_num() const {
		return _root_num;
	}

	const QString& location() const {
		return _loc;
	}

	int id() const { return _id; }

	bool ensureLoaded();
	template<typename T> void mapData(const T* dat, char* cube, int64_t w, int64_t h, int64_t d, int64_t x0, int64_t y0, int64_t z0, int64_t xstride, int64_t ystride) const;
};

class AnnotModel : public QAbstractItemModel {
	Q_OBJECT;
	const AnnotTree& tree;
	public:
	AnnotModel(QObject* s, const AnnotTree& t);
	int columnCount(const QModelIndex& parent=QModelIndex()) const override;
	QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const override;
	Qt::ItemFlags flags(const QModelIndex& index) const override;
	bool hasChildren(const QModelIndex& parent=QModelIndex()) const override;
	QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override;
	QModelIndex index(int row, int column, const QModelIndex& parent=QModelIndex()) const override;
	QModelIndex parent(const QModelIndex& index) const override;
	int rowCount(const QModelIndex& parent=QModelIndex()) const override;

	bool setData(const QModelIndex& index, const QVariant& value, int role=Qt::EditRole) override;

	bool contains(const AnnotTree* t) const { return &tree==t; }
	QString getPath(uint32_t id) const;
};

#endif
